package com.kitty.game.merge;


import com.kitty.common.db.BaseEntityGame;
import com.kitty.common.mysql.TargetDataSource;
import com.kitty.common.utils.SpringUtils;
import com.kitty.common.thread.NamedThreadFactory;
import com.kitty.common.utils.BlockingUniqueQueue;
import com.kitty.game.ServerService;
import com.kitty.game.party.model.Party;
import com.kitty.game.role.model.Account;
import com.kitty.game.role.model.Role;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 公共数据(排查玩家数据)持久化队列
 */
@Service
public class Merge2DBService {

    @Autowired
    ServerService serverService;
    Logger logger = LoggerFactory.getLogger(getClass());
    private static volatile Merge2DBService instance;

    @Autowired
    private Dao dao;

    public static Merge2DBService getInstance() {
        return instance;
    }

    /**
     * start consumer thread
     */
    public void init() {
        for (int i=0;i<32;i++){
            new NamedThreadFactory("db-common-save-service-"+i).newThread(new Worker()).start();
        }
        logger.info("初始化合区线程32条");
        instance = this;
    }

    private BlockingQueue<BaseEntityGame> queue = new BlockingUniqueQueue<>();

    private final AtomicBoolean run = new AtomicBoolean(true);

    public void add2Queue(BaseEntityGame entity) {
        if (entity == null) {
            return;
        }
        this.queue.add(entity);
//        logger.error("入库队列大小==={}",queue.size());
    }

    private class Worker implements Runnable {
        @Override
        public void run() {
            while (run.get()) {
                BaseEntityGame entity = null;
                try {
//                    long old = System.currentTimeMillis();
                    entity = queue.take();
                    SpringUtils.getBean(Merge2DBService.class).saveToDb(entity);
//                    logger.error("消耗时间=={}=={}",(System.currentTimeMillis()-old),queue.size());
                } catch (Exception e) {

                    // 有可能是并发抛错，重新放入队列
//                    add2Queue(entity);
                }
                logger.error("队列剩余数量=={}",queue.size());
            }
        }
    }

    /**
     * 数据真正持久化
     *
     * @param entity
     */
    @TargetDataSource(name = "adb")
    public void saveToDb(BaseEntityGame entity) {
//        entity.doBeforeSave();
        dao.insertOrUpdate(entity);
    }

    @TargetDataSource(name = "adb")
    public int fetchRole(Role role){
        return dao.count(Role.class, Cnd.where("name", "=", role.getName()));
    }
    @TargetDataSource(name = "adb")
    public int fetchParty(Party party){
        return dao.count(Party.class, Cnd.where("partyName", "=", party.getPartyName()));
    }

    @TargetDataSource(name = "adb")
    public Account fetchAccount(Account account){
        return dao.fetch(Account.class, Cnd.where("id", "=", account.getId()));
    }
    @TargetDataSource(name = "adb")
    public void saveToDb111(BaseEntityGame entity) {
        entity.doBeforeSave();
        LoggerFactory.getLogger(getClass()).error("id==={}", Json.toJson(entity, JsonFormat.compact()));
        if (entity.isDelete()) {
            dao.delete(entity);
        } else {
            dao.insertOrUpdate(entity);
        }
    }
}